package com.journey.org.app

import com.google.gson.GsonBuilder
import com.jakewharton.retrofit2.adapter.kotlin.coroutines.CoroutineCallAdapterFactory
import com.mvvmhabit.org.BaseApplication
import com.mvvmhabit.org.BuildConfig
import com.mvvmhabit.org.base.BAO_BA_B_BASE_URL
import com.mvvmhabit.org.http.AndroidScheduler
import com.mvvmhabit.org.http.interceptor.BaseInterceptor
import com.mvvmhabit.org.http.logging.Level
import com.mvvmhabit.org.http.logging.LoggingInterceptor
import com.mvvmhabit.org.utils.HttpsUtil
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.schedulers.Schedulers
import okhttp3.Cache
import okhttp3.ConnectionPool
import okhttp3.OkHttpClient
import okhttp3.internal.platform.Platform
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

class RetrofitOtherManager {

    //超时时间
    private val DEFAULT_TIMEOUT = 15

    //缓存时间
    private val CACHE_TIMEOUT = 15 * 1024 * 1024

    // 上下文
    private val mContext = BaseApplication.getInstance()?.applicationContext

    //
    private var mOkHttpClient: OkHttpClient

    //
    private var mRetrofit: Retrofit

    // 缓存
    private var mCache: Cache? = null

    // 缓存文件
    private var mCacheFile: File? = null

    // 请求接口 前缀
    //   private val BASE_URL = BAO_BA_B_BASE_URL

    companion object {
        private var instance: RetrofitOtherManager? = null

        /**
         * 单例模式
         *
         * @return
         */
        @Synchronized
        fun getInstance(): RetrofitOtherManager? {
            if (instance == null) {
                instance = RetrofitOtherManager()
            }
            return instance
        }

        /**
         * 单例模式
         *
         * @return
         */
        @Synchronized
        fun getInstance(baseUrl: String): RetrofitOtherManager? {
            if (instance == null) {
                instance = RetrofitOtherManager(baseUrl)
            }
            return instance
        }

        /**
         * 单例模式
         *
         * @return
         */
        @Synchronized
        fun getInstance(baseUrl: String, header: Map<String, String>): RetrofitOtherManager? {
            if (instance == null) {
                instance = RetrofitOtherManager(baseUrl, header)
            }
            return instance
        }
    }

    constructor() : this(baseUrl = BAO_BA_B_BASE_URL, header = null)

    constructor(baseUrl: String) : this(baseUrl, null)

    constructor(baseUrl: String, header: Map<String, String>?) {
        // 判断缓存文件是否为空
        if (mCacheFile == null) {
            // 创建缓存文件
            mCacheFile = File(mContext?.cacheDir, "resolute_cache")
        }
        try {
            // 判断缓存类是否为空
            if (mCache == null) {
                // 创建缓存类 参数一：缓存的文件地址 参数二：缓存的时间
                mCache = Cache(mCacheFile!!, CACHE_TIMEOUT.toLong())
            }
        } catch (e: Exception) {
            // Log.e("Could not create http cache",e.message)
        }
        val sslParams = HttpsUtil.getSslSocketFactory()
        mOkHttpClient = OkHttpClient.Builder()
            //.cookieJar(CookieJarImpl(PersistentCookieStore(mContext)))
            .cache(mCache)
            .addInterceptor(BaseInterceptor(header))
            // .addInterceptor(CacheInterceptor())
            .sslSocketFactory(sslParams.sSLSocketFactory, sslParams.trustManager)
            // .hostnameVerifier(HttpsUtil.UnSafeHostnameVerifier) // 证书不验证
            .addInterceptor(
                LoggingInterceptor.Builder()
                    .loggable(BuildConfig.DEBUG)
                    .setLevel(Level.BASIC)
                    .log(Platform.INFO)
                    .request("Request") // request的Tag
                    .response("Response")// Response的Tag
                    .addHeader(
                        "log-header",
                        "I am the log request header."
                    ) // 添加打印头, 注意 key 和 value 都不能是中文
                    .build()
            )
            .connectTimeout(DEFAULT_TIMEOUT.toLong(), TimeUnit.SECONDS)
            .writeTimeout(DEFAULT_TIMEOUT.toLong(), TimeUnit.SECONDS)
            .connectionPool(ConnectionPool(8, 15, TimeUnit.SECONDS))
            // 这里你可以根据自己的机型设置同时连接的个数和时间，我这里8个，和每个保持时间为10s
            .build()
        mRetrofit = Retrofit.Builder()
            .client(mOkHttpClient)
            .addCallAdapterFactory(CoroutineCallAdapterFactory())
            .addConverterFactory(GsonConverterFactory.create(GsonBuilder().create()))
            .baseUrl(baseUrl)
            .build()
    }

    /**
     * create you ApiService
     * Create an implementation of the API endpoints defined by the `service` interface.
     */
    fun <T> create(service: Class<T>?): T {
        if (service == null) {
            throw RuntimeException("Api service is null!")
        }
        return mRetrofit.create(service)
    }

    fun <T> execute(observable: Observable<T>, subscriber: Observer<T>): T? {
        observable.subscribeOn(Schedulers.io())
            .unsubscribeOn(Schedulers.io())
            .observeOn(AndroidScheduler.mainThread())
            .subscribe(subscriber)
        return null
    }
}